﻿using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TimeTracker.SqlLiteProvider
{
    [Description("SQLite database")]
    public partial class Provider : TimeTracker.IProvider, IDisposable
    {
        private string connectionString = String.Empty;
        protected string ConnectionString
        {
            get
            {
                if (String.IsNullOrEmpty(this.connectionString))
                {
                    string connectionStringFormat = "metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SQLite;provider connection string='data source=\"{log-file-path}\"'";

                    this.connectionString = connectionStringFormat.Replace("{log-file-path}", this.LogFilePath);
                }
                return this.connectionString;
            }
        }

        protected string AppDataFolderPath
        {
            get
            {
                string appDataFolderPath = System.IO.Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "TimeTracker");

                if (!System.IO.Directory.Exists(appDataFolderPath))
                {
                    System.IO.Directory.CreateDirectory(appDataFolderPath);
                }

                return appDataFolderPath;
            }
        }

        protected string LogFilePath
        {
            get { 
                string path = System.IO.Path.Combine(this.AppDataFolderPath, "Log.db3");

                if (!System.IO.File.Exists(path))
                {
                    using (System.IO.FileStream stream = System.IO.File.Create(path))
                    {
                        byte[] blankLog = Resource1.blank_log;

                        stream.Write(blankLog, 0, blankLog.Length);

                        stream.Close();
                    }
                }

                return path;
            
            }
        }

        private LogEntities entities;
        protected LogEntities Entities
        {
            get
            {
                if (this.entities == null)
                {
                    this.entities = new LogEntities(this.ConnectionString);
                }

                return this.entities;
            }
        }

        IEnumerable<IProject> IProvider.GetProjects()
        {
            return this.Entities.Projects.Select<Project, IProject>(r => r);
        }

        IProject IProvider.CreateProject(IProject parentProject, string name)
        {
            Project project = new Project()
            {
                Name = name
            };

            if (parentProject != null)
            {
                ((Project)parentProject).Projects.Add(project);
            }
            else
            {
                this.Entities.Projects.AddObject(project);
            }

            return (IProject)project;
        }

        ISession IProvider.CreateSession(IProject project, DateTime start, DateTime? end)
        {
            Session session = new Session()
            {
                StartTime = start,
                StopTime = end
            };

            ((Project)project).Sessions.Add(session);

            return (ISession)session;
        }

        INote IProvider.CreateNote(ISession session, DateTime time, string text)
        {
            Note note = new Note()
            {
                Time = time,
                Text = text
            };

            ((Session)session).Notes.Add(note);

            return (INote)note;
        }

        void IProvider.RemoveProject(IProject project)
        {
            Project entity = (Project)project;

            foreach (Session session in entity.Sessions.ToArray())
            {
                foreach (Note note in session.Notes.ToArray())
                {
                    session.Notes.Remove(note);
                    this.Entities.Notes.DeleteObject(note);
                }

                entity.Sessions.Remove(session);
                this.Entities.Sessions.DeleteObject(session);
            }

            foreach (Project childProject in project.Projects.ToArray())
            {
                ((IProvider)this).RemoveProject(childProject);
            }

            this.Entities.Projects.DeleteObject(entity);
        }

        void IProvider.RemoveSession(ISession session)
        {
            Session entity = (Session)session;

            foreach (Note note in entity.Notes.ToArray())
            {
                entity.Notes.Remove(note);
                this.Entities.Notes.DeleteObject(note);
            }
            
            this.Entities.Sessions.DeleteObject(entity);
        }

        void IProvider.RemoveNote(INote note)
        {
            Note entity = (Note)note;

            this.Entities.Notes.DeleteObject(entity);
        }

        System.Xml.XmlDocument IProvider.GetXmlDocument()
        {
            throw new NotImplementedException();
        }

        void IProvider.Save()
        {
            this.Entities.SaveChanges();
        }

        void IDisposable.Dispose()
        {
            //this.entities = null;
        }
    }
}
